import { Application_Json } from "@/utils/keyWord"
import { useAuthStore }  from "@/store"
import { createOverload } from '@/security/overload'


export const get = createOverload()
const deviceInfo = uni.getDeviceInfo()

get.addImpl('string', (url: string) => {
  return commander(url, null, "GET",  true, Application_Json);
})

get.addImpl('string', "boolean", (url: string,  isAuth: boolean) => {
  return commander(url, null, "GET", isAuth, Application_Json);
})

get.addImpl('string', 'object', (url: string, data: object) => {
  return commander(url, data, "GET",  true, Application_Json);
})
get.addImpl('string',  'object', 'boolean', (url: string, data: object, isAuth: boolean) => {
  return commander(url, data, "GET",  isAuth, Application_Json);
})


get.addImpl("string", 'object', "string",  (url: string, data: object, contentType: string) => {
  return commander(url, data, "GET",  true, contentType);
})

get.addImpl("string", "object", 'boolean', "string",(url: string, data: object, isAuth: boolean, contentType: string) => {
  return commander(url, data, "GET",  isAuth, contentType);
})


export const post = createOverload()

post.addImpl('string', (url: string) => {
  return commander(url, null, "POST",  true, Application_Json);
})

post.addImpl('string', "object", (url: string, data: object) => {
  return commander(url, data, "POST",  true, Application_Json);
})

post.addImpl('string', "object", "boolean", (url: string, data: object, isAuth: boolean) => {
  return commander(url, data, "POST",  isAuth, Application_Json);
})

post.addImpl('string', "object", "string", (url: string, data: object, contentType: string) => {
  return commander(url, data, "POST",  true,  contentType);
})

post.addImpl("string", "object", 'boolean', "string",(url: string, data: object, isAuth: boolean, contentType: string) => {
  return commander(url, data, "POST",  isAuth, contentType);
})


export const put = createOverload()

put.addImpl('string', "object", (url: string, data: object) => {
  return commander(url, data, "PUT",  true, Application_Json);
})

put.addImpl('string', "object", "boolean", (url: string, data: object, isAuth: boolean) => {
  return commander(url, data, "PUT",  isAuth, Application_Json);
})

put.addImpl('string', "object", "string", (url: string, data: object, contentType: string) => {
  return commander(url, data, "PUT",  true,  contentType);
})

put.addImpl("string", "object", 'boolean', "string",(url: string, data: object, isAuth: boolean, contentType: string) => {
  return commander(url, data, "PUT",  isAuth, contentType);
})

export const remove = createOverload()

remove.addImpl('string', (url: string, data: object) => {
  return commander(url, null, "DELETE",  true, Application_Json);
})

remove.addImpl('string', "object", (url: string, data: object) => {
  return commander(url, data, "DELETE",  true, Application_Json);
})

remove.addImpl('string', "object", "boolean", (url: string, data: object, isAuth: boolean) => {
  return commander(url, data, "DELETE",  isAuth, Application_Json);
})

remove.addImpl('string', "object", "string", (url: string, data: object, contentType: string) => {
  return commander(url, data, "DELETE",  true,  contentType);
})

remove.addImpl("string", "object", 'boolean', "string",(url: string, data: object, isAuth: boolean, contentType: string) => {
  return commander(url, data, "DELETE",  isAuth, contentType);
})


export const uploadFile =(url: string, filePath: string, formData?: object)  => {
  const header: any = {
    'platform':  deviceInfo.platform, 
    'system':  deviceInfo.system, 
    'deviceBrand':  deviceInfo.deviceBrand, 
    'deviceModel':  deviceInfo.deviceModel, 
    'deviceType':  deviceInfo.deviceType, 
  }
  authorization(header);
  return uploadSingleFile(url, filePath, formData, header);
}





// uploadFiles

/**
 *  请求统一处理
 * @param url 
 * @param data 
 * @param method 
 * @param isAuth 
 * @param contentType 
 * @returns 
 */
function commander(url: string, 
                   data: any, 
                   method: string, 
                   isAuth: boolean | undefined, 
                   contentType?: string): Promise<any>{

  const header: any = {
    "Content-Type":   contentType || Application_Json,
    'platform':  deviceInfo.platform, 
    'system':  deviceInfo.system, 
    'deviceBrand':  deviceInfo.deviceBrand, 
    'deviceModel':  deviceInfo.deviceModel, 
    'deviceType':  deviceInfo.deviceType, 
  }
  isAuth = (isAuth === undefined || null) ? true : isAuth;
  // 验证是否需要带token
  if(isAuth){
    authorization(header)
  } 
  return request(url, data, method, header)
}


/**
 *  授权
 * @param header 
 * @returns 
 */
function authorization(header: any){
    const authStore = useAuthStore()
    const authorization = authStore.getAccessToken()
    if(authorization){
        header['Authorization'] = authorization
    }
}


/**
 *  发送请求
 * @param url  
 * @param data 
 * @param method 
 * @param header 
 * @param options 
 * @returns 
 */
function request(url: string, data: any, method: any, header: any, options?: Object){
   return new Promise((resolve, reject) =>{
      uni.request({
          url,
          data: data || {},
          method,
          header,
          ...options,
          success: (res: any) => {
              if(res.statusCode === 200 && res.data.code ==='00000'){
                resolve(res.data)     
              }else{
                reject(res.data)
              }
            },
            fail: (err: any) => {
              reject(err)
            }
      })
   })
}

/**
 *  上传文件
 * @param url  
 * @param filePath 
 * @param formData 
 * @param header 
 * @param options 
 * @returns 
 */
 function uploadSingleFile(url: string, filePath: string, formData: any, header: any, options?: Object): Promise<any>{
  return new Promise((resolve, reject) =>{
    uni.uploadFile({
      url,
      filePath,
      timeout: 180000,
      formData,
      name: "file",
      header,
      ...options,
      success: (res :any) => {
        if(res.statusCode === 200){
          resolve(res.data)     
        }else{
          reject(res.data)
        }
      },
      fail: (err: any) => {
        reject(err)
      }
    })
  })
}